
#include <ctime>
#include <BClock>
#include "member_BClock.h"

using namespace BWE;

#define member					(*(member_BClock*)_ptr)
#define member_allocate()		_ptr = new member_BClock
#define member_release()		delete (member_BClock*)_ptr

#ifdef _LINUX_
#include <time.h>

BString BClock::GetTime()
{
	time_t raw_time = ::time(0); 
	tm* gtime = gmtime(&raw_time);
	char* ascg = asctime(gtime);
	return ascg;
}
BString BClock::GetLocalTime()
{
	time_t raw_time = ::time(0); 
	tm* ltime = localtime(&raw_time);
	char* ascl = asctime(ltime);
	return ascl;
}

BClock::BClock()
{
	member_allocate();
}
BClock::~BClock()
{
	member_release();
}

double BClock::start()
{
	timespec ts;
	int ret = clock_gettime(CLOCK_REALTIME, &ts);
	member.startTime = ts.tv_sec + ts.tv_nsec * 0.000000001;
	return time();
}

double BClock::time()
{
	timespec ts;
	clock_gettime(CLOCK_REALTIME, &ts);
	member.tickTime = ts.tv_sec + ts.tv_nsec * 0.000000001;
	return member.tickTime - member.startTime;
}

double BClock::stop()
{
	double time = this->time();
	member.startTime = 0;
	member.tickTime = 0;
	return time;
}

bool BClock::sleep(double seconds)
{
	timespec ts;
	ts.tv_sec = seconds;
	ts.tv_nsec = (seconds - ts.tv_sec) * 1000000000;
	if(clock_nanosleep(CLOCK_REALTIME, CLOCK_REALTIME, &ts, 0) != 0)
		return false;
	return true;
}
#endif

#ifdef _WINDOWS_SYSTEM_
BClock::BClock()
{
	member_allocate();
}
BClock::~BClock()
{
	member_release();
}

double BClock::start()
{
	member.startTime = member.tick();
	member.tickTime = member.startTime;
	return 0;
}
double BClock::time()
{
	member.tickTime = member.tick();
	return member.tickTime - member.startTime;
}
double BClock::stop()
{
	double time = this->time();
	member.startTime = 0;
	member.tickTime = 0;
	return time;
}

bool BClock::sleep(double sceconds)
{
	if (!member.htimer)
		member.htimer = ::CreateWaitableTimer(0, 0, 0);

	if (!member.htimer)
		return false;

	LARGE_INTEGER time;
	time.QuadPart = (LONGLONG)(sceconds * -10000000);

	if (SetWaitableTimer(member.htimer, &time, 0, 0, 0, 0) == false)
		return false;

	if (WaitForSingleObject(member.htimer, INFINITE) == WAIT_FAILED)
		return false;

	return true;
}
#endif
